/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.search.types; import java.io.*; import java.util.*; import java.text.*; import org.openide.util.*; import org.openide.loaders.*; import org.openide.filesystems.*; import org.apache.regexp.*; import org.netbeans.modules.search.res.*; /** * Test DataObject primaryFile for modificaion date. * <p>There are mutually exclusive criteria: between and days. * Between represents absolute date interval. Days represents * relative interval related to today. * * <p>Internally uses null as wildcard. It is presented as WILDCARD string. * One of between or days must be null. * * @author Petr Kuzel * @version 1.0 */ public class ModificationDateType extends DataObjectType { public static final long serialVersionUID = 4L; public static final String PROP_DAYS = "days"; // NOI18N public static final String PROP_BEFORE = "before"; // NOI18N public static final String PROP_AFTER = "after"; // NOI18N private transient boolean TRACE = false; /** Holds value of property matchBefore. */ private Date matchBefore; /** Holds value of property matchAfter. */ private Date matchAfter; /** Holds value of property day. */ private Short days; /** Creates new FullTextType */ public ModificationDateType() { } /** */ public String toString() { return "ModificationDateType: days:" + days + " after:" + matchAfter + " before:" + matchBefore ; // NOI18N } /** * Does the DataObject pass this criterion? * @param dataobject to be examined * @return true if pass */ public boolean test (DataObject dobj) { FileObject fo = dobj.getPrimaryFile(); // it is strange if (fo == null) return false; // Primary File Modification Date Date date = fo.lastModified(); t("file:" + fo + " modified:" + date); // NOI18N boolean hit = testDays(date) && testAfter(date) && testBefore(date); if (hit) addDetail(Res.text("DETAIL_DATE") + new FormattedDate(date).toString()); // NOI18N return hit; } /** Is within range? */ private boolean testAfter(Date date) { if (matchAfter == null) return true; return date.compareTo(matchAfter)>=0; } /** Is within range? */ private boolean testBefore(Date date) { if (matchBefore == null) return true; return date.compareTo(matchBefore)<=0; } /** Is within 24 hours range? */ private boolean testDays(Date date) { if (days == null) return true; return (System.currentTimeMillis() - date.getTime()) < days.shortValue()*1000L*60L*60L*24L; } /** ??? */ public String getDisplayName() { return Res.text("DATE_CRITERION"); // NOI18N } // -------------- before ------------------- /** Getter for property matchBefore. *@return Value of property matchBefore. */ public Date getMatchBeforeAsDate() { return new FormattedDate(matchBefore); } public String getMatchBefore() { if (matchBefore == null) return WILDCARD; else return getMatchBeforeAsDate().toString(); } /** Setter for property. * @param String to be parsed * @throw IllegalArgumentException if null passed */ public void setMatchBefore(String before) { try { setMatchBeforeImpl(before); setValid(true); } catch (IllegalArgumentException ex) { setValid(false); throw ex; } } private void setMatchBeforeImpl(String matchBefore) { if (matchBefore == null) throw new IllegalArgumentException(); if (matchBefore.equals(WILDCARD)) { setMatchBeforeByDate(null); return; } try { setMatchBeforeByDate(new FormattedDate(matchBefore)); } catch (ParseException ex) { throw new IllegalArgumentException(); } } /** Setter for property matchBefore. *@param matchBefore New value of property matchBefore. */ public void setMatchBeforeByDate(Date matchBefore) { //let date represent one milisecond before midnight if (matchBefore != null) { GregorianCalendar cal = new GregorianCalendar(); cal.setTime(matchBefore); cal.set(cal.HOUR_OF_DAY, cal.getActualMaximum(cal.HOUR_OF_DAY)); cal.set(cal.MINUTE, cal.getActualMaximum(cal.MINUTE)); cal.set(cal.SECOND, cal.getActualMaximum(cal.SECOND)); cal.set(cal.MILLISECOND, cal.getActualMaximum(cal.MILLISECOND)); matchBefore = cal.getTime(); } //do it Date old = this.matchBefore; this.matchBefore = matchBefore; days = null; firePropertyChange(PROP_BEFORE, old, matchBefore); firePropertyChange(PROP_DAYS, null, null); } // --------------- after --------------- /** Getter for property matchAfter. *@return Value of property matchAfter. */ public Date getMatchAfterAsDate() { return new FormattedDate(matchAfter); } public String getMatchAfter() { if (matchAfter == null) return WILDCARD; else return getMatchAfterAsDate().toString(); } /** Setter for property. * @param String to be parsed * @throw IllegalArgumentException if null passed */ public void setMatchAfter(String after) { try { setMatchAfterImpl(after); setValid(true); } catch (IllegalArgumentException ex) { setValid(false); throw ex; } } private void setMatchAfterImpl(String matchAfter) { if (matchAfter == null) throw new IllegalArgumentException(); if (matchAfter.equals(WILDCARD)) { setMatchAfterByDate(null); return; } try { setMatchAfterByDate(new FormattedDate(matchAfter)); } catch (ParseException ex) { throw new IllegalArgumentException(); } } /** Setter for property matchAfter. *@param matchAfter New value of property matchAfter. */ public void setMatchAfterByDate(Date matchAfter) { //let date represent midnight if (matchAfter != null) { GregorianCalendar cal = new GregorianCalendar(); cal.setTime(matchAfter); cal.set(cal.HOUR_OF_DAY, cal.getActualMinimum(cal.HOUR_OF_DAY)); cal.set(cal.MINUTE, cal.getActualMinimum(cal.MINUTE)); cal.set(cal.SECOND, cal.getActualMinimum(cal.SECOND)); cal.set(cal.MILLISECOND, cal.getActualMinimum(cal.MILLISECOND)); matchAfter = cal.getTime(); } //do it Date old = this.matchAfter; this.matchAfter = matchAfter; days = null; firePropertyChange(PROP_AFTER, old, matchAfter); firePropertyChange(PROP_DAYS, null, null); } // ------------ days handling ---------------------- /** Getter for property day. *@return Value of property day. */ public Short getDaysAsShort() { return days; } public String getDays() { if (days == null) return WILDCARD; else return days.toString(); } /** Setter for property day. * @param String to be parsed as short */ public void setDays(String days) { try { setDaysImpl(days); setValid(true); } catch (IllegalArgumentException ex) { setValid(false); throw ex; } } public void setDaysImpl(String days) { if (days.equals(WILDCARD)) { setDaysByShort(null); return; } try { DecimalFormat format = new DecimalFormat(); setDaysByShort(new Short(format.parse(days).shortValue())); } catch (ParseException ex) { throw new IllegalArgumentException(); } } /** Setter for property day. *@param day New value of property day. */ private void setDaysByShort(Short days) { Short old = this.days; this.days = days; matchAfter = null; matchBefore = null; firePropertyChange(PROP_DAYS, old, days); firePropertyChange(PROP_AFTER, null, null); firePropertyChange(PROP_BEFORE, null, null); } // --------------- INNER --------------------------- /** * Date using default locale formatting. * Provide overridden constructor and toString() method. */ static class FormattedDate extends Date { /** Default locale formattor. */ private static DateFormat format; private transient boolean isNull = true; /** Init static fields. */ static { format = new SimpleDateFormat().getDateInstance(); // bugfix accepts dates like Dec -1, 1999 = Nov 29 // format.setLenient(true); } /** Create new object. * @param date null is ambiguous -> today. */ public FormattedDate(Date date) { super(date == null ? new Date().getTime() : date.getTime() ); isNull = date == null; } /** * Create new object. * @param Use default locale formatting while parsing date. */ public FormattedDate(String date) throws ParseException { super( format.parse(date).getTime() ); isNull = date == null; } /** Use defalt locale formatting. */ public String toString() { return format.format(this); } /** * Extra handling of equals(null). Return true if * this Date represents wildcard value. */ public boolean equals(Object obj){ if (obj == null && isNull) return true; else return super.equals(obj); } } private void t(String msg) { if (TRACE) System.err.println("CriteriaM: " + msg); } public HelpCtx getHelpCtx() { return new HelpCtx (ModificationDateType.class); } public String getTabText() { return Res.text("DATE_CRITERION"); // NOI18N } } /* * Log * 15 Gandalf-post-FCS1.13.1.0 4/4/00 Petr Kuzel Comments + output window * fix * 14 Gandalf 1.13 1/18/00 Jesse Glick Context help. * 13 Gandalf 1.12 1/13/00 Radko Najman I18N * 12 Gandalf 1.11 1/11/00 Petr Kuzel Result details added. * 11 Gandalf 1.10 1/10/00 Petr Kuzel "valid" fired. * 10 Gandalf 1.9 1/7/00 Petr Kuzel Lenient date parsing * fixed. * 9 Gandalf 1.8 1/5/00 Petr Kuzel Margins used. Help * contexts. * 8 Gandalf 1.7 1/4/00 Petr Kuzel Bug hunting. * 7 Gandalf 1.6 12/23/99 Petr Kuzel Architecture improved. * 6 Gandalf 1.5 12/20/99 Petr Kuzel L&F fixes. * 5 Gandalf 1.4 12/17/99 Petr Kuzel Bundling. * 4 Gandalf 1.3 12/16/99 Petr Kuzel * 3 Gandalf 1.2 12/15/99 Petr Kuzel * 2 Gandalf 1.1 12/15/99 Martin Balin Fixed package name * 1 Gandalf 1.0 12/14/99 Petr Kuzel * $ */